/**
 * 梗概：
 *      元字符
 *      字符转义
 *      重复
 *      字符类
 *      分支条件
 *      分组
 *      反义
 *      后向引用   
 * 
 * @func 1-元字符
 *      .   匹配除换行符以外的任意字符
 *      \w  匹配字母或数字或下划线或汉字
 *      \s  任意的空白符
 *      \d  数字
 *      \b  单词的开始或结束
 *      ^   字符串的开始
 *      $   字符串的结束
 * 
 *  ^ $ 开头结尾 配合使用正则
 *      如要求你填写的QQ号必须为 5 位到 12 位数字 ^\d{5,12}$
 * 
 * @func 2-转义
 *      如查找关键词 * .等
 *      使用 \ 来取消这些字符的特殊意义
 *      * .
 *      ===> \* \.
 *      yuque\.com      C:\\Windows <= C:\Windows
 * 
 * @func 3-重复
 *      ?       重复零次或一次
 *      {n}     重复n次
 *      {n,}    重复n或更多次
 *      {n,m}   重复n-m次
 * @func 4-字符
 *      匹配字符集合
 *      [aeiou]就匹配任何一个英文元音字母
 *      [.?!]匹配标点符号(.或?或!)
 *      [0-9] 0-9的数字
 * @func 5-分枝条件
 *      正则表达式里的分枝条件指的是有几种规则，如果满足其中任意一种规则都应该当成匹配
 *      具体方法是用|把不同的规则分隔开
 * 
 *      0\d{2}-\d{8}|0\d{3}-\d{7}
 *      ===> 匹配两种以连字号分隔的电话号码
 *          1.三位区号  
 *          2.4位区号
 * 
 *      注意各个条件的顺序
 *      匹配分枝条件时，将会从左到右地测试每个条件，如果满足了某个分枝的话，就不会去再管其它的条件
 * 
 * 
 * @func 6-分组
 *      当重复单个字符时
 *      ===> 在字符后面加上限定符
 *      当想重复多个字符呢？
 *      ===> 小括号来指定子表达式
 *      
 *      栗子
 *          (\d{1,3}.){3}\d{1,3}    一个简单的IP地址匹配表达式
 *          但它也将匹配256.300.888.999这种不可能存在的IP地址
 *          只能使用冗长的分组，选择，字符类来拼凑正常的正则
 *          ===> ((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
 * 
 * @func 7-反义
 *      反义词的那个反义
 *      \W	匹配任意不是字母，数字，下划线，汉字的字符
        \S	匹配任意不是空白符的字符
        \D	匹配任意非数字的字符
        \B	匹配不是单词开头或结束的位置
        [^x]	匹配除了x以外的任意字符
        [^aeiou]	匹配除了aeiou这几个字母以外的任意字符


        栗子
            [^aeiou]	匹配除了aeiou这几个字母以外的任意字符
            <a[^>]+>    匹配用尖括号括起来的以a开头的字符串
            \S+匹配不包含空白符的字符串


    @func 8-后向引用
        使用小括号指定一个子表达式后，匹配这个子表达式的文本
        后向引用用于重复搜索前面某个分组匹配的文本

        栗子
            \b(\w+)\b\s+\1\b可以用来匹配重复的单词

                (\b(\w+)\b)==》  单词开始处和结束处之间的多于一个的字母或数字
                这个单词会被捕获到编号为1的分组中，然后是1个或几个空白符(\s+)
                最后是分组1中捕获的内容（也就是前面匹配的那个单词）(\1)

        常用分组语法
            捕获	(exp)	匹配exp,并捕获文本到自动命名的组里
            (?exp)	匹配exp,并捕获文本到名称为name的组里，也可以写成(?'name'exp)
            (?:exp)	匹配exp,不捕获匹配的文本，也不给此分组分配组号
            零宽断言	(?=exp)	匹配exp前面的位置
            (?<=exp)	匹配exp后面的位置
            (?!exp)	匹配后面跟的不是exp的位置
            (?<!exp)	匹配前面不是exp的位置
 */